From 6ac09efa8f0e189ffe7dd7b0889289de56ee44cc Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 19 Jan 2014 12:18:03 +0100
Subject: [PATCH] USB: EHCI: allow limiting ports for ehci-platform

In the same way as the ohci platform driver allows limiting ports,
enable the same for ehci. This prevents a mismatch in the available
ports between ehci/ohci on USB 2.0 controllers.

This is needed if the USB host controller always reports the maximum
number of ports regardless of the number of available ports (because
one might be set to be usb device).

Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
 drivers/usb/host/ehci-hcd.c      | 4 ++++
 drivers/usb/host/ehci-platform.c | 2 ++
 drivers/usb/host/ehci.h          | 1 +
 include/linux/usb/ehci_pdriver.h | 1 +
 4 files changed, 8 insertions(+)

--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -666,6 +666,10 @@ int ehci_setup(struct usb_hcd *hcd)
 
 	/* cache this readonly data; minimize chip reads */
 	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+	if (ehci->num_ports) {
+		ehci->hcs_params &= ~0xf; /* bits 3:0, ports on HC */
+		ehci->hcs_params |= ehci->num_ports;
+	}
 
 	ehci->sbrn = HCD_USB2;
 
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -60,6 +60,9 @@ static int ehci_platform_reset(struct us
 
 	ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug;
 
+	if (pdata->num_ports && pdata->num_ports <= 15)
+		ehci->num_ports = pdata->num_ports;
+
 	if (pdata->pre_setup) {
 		retval = pdata->pre_setup(hcd);
 		if (retval < 0)
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -213,6 +213,7 @@ struct ehci_hcd {			/* one per controlle
 	u32			command;
 
 	/* SILICON QUIRKS */
+	unsigned int		num_ports;
 	unsigned		no_selective_suspend:1;
 	unsigned		has_fsl_port_bug:1; /* FreeScale */
 	unsigned		has_fsl_hs_errata:1;	/* Freescale HS quirk */
--- a/include/linux/usb/ehci_pdriver.h
+++ b/include/linux/usb/ehci_pdriver.h
@@ -42,6 +42,7 @@ struct usb_hcd;
  */
 struct usb_ehci_pdata {
 	int		caps_offset;
+	unsigned int	num_ports;
 	unsigned	has_tt:1;
 	unsigned	has_synopsys_hc_bug:1;
 	unsigned	big_endian_desc:1;
